/**
 * Copyright &copy; 2012-2014 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 */
package com.thinkgem.jeesite.modules.borrow.service;

import com.thinkgem.jeesite.common.persistence.Page;
import com.thinkgem.jeesite.common.persistence.Result;
import com.thinkgem.jeesite.common.service.CrudService;
import com.thinkgem.jeesite.common.utils.DateUtils;
import com.thinkgem.jeesite.common.utils.RandomNumUtiles;
import com.thinkgem.jeesite.common.utils.StringUtils;
import com.thinkgem.jeesite.modules.book.dao.BookStoreDao;
import com.thinkgem.jeesite.modules.book.entity.BkBookinfo;
import com.thinkgem.jeesite.modules.book.entity.BkBookstore;
import com.thinkgem.jeesite.modules.book.service.BookMgrService;
import com.thinkgem.jeesite.modules.book.service.BookStoreService;
import com.thinkgem.jeesite.modules.borrow.dao.BorrowContinueDao;
import com.thinkgem.jeesite.modules.borrow.dao.BorrowDao;
import com.thinkgem.jeesite.modules.borrow.dao.BorrowLogDao;
import com.thinkgem.jeesite.modules.borrow.entity.Borrow;
import com.thinkgem.jeesite.modules.borrow.entity.BorrowLog;
import com.thinkgem.jeesite.modules.reader.entity.Reader;
import com.thinkgem.jeesite.modules.reader.entity.ReaderRolePlace;
import com.thinkgem.jeesite.modules.reader.entity.ReaderRoler;
import com.thinkgem.jeesite.modules.reader.service.ReadersService;
import com.thinkgem.jeesite.modules.sys.utils.UserUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.sql.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.List;
import java.util.Map;

/**
 * 系统管理，安全相关实体的管理类,包括用户、角色、菜单.
 * @author ThinkGem
 * @version 2013-12-05
 */
@Service
@Transactional(readOnly = true)
public class BorrowService extends CrudService<BorrowDao, Borrow>{
	@Autowired
	private BorrowDao borrowDao;

	@Autowired
	private BorrowContinueDao borrowContinueDao;

	@Autowired
	private BorrowLogDao borrowLogDao;

    @Autowired
    private BookStoreDao bookStoreDao;

	@Autowired
	private ReadersService readerService;

	@Autowired
	private BookStoreService bookStoreService;

	@Autowired
	private BookMgrService bookMgrService;

	public Page<Borrow> findBorrow(Page<Borrow> page, Borrow borrow) {
		// 生成数据权限过滤条件（dsf为dataScopeFilter的简写，在xml中使用 ${sqlMap.dsf}调用权限SQL）
		borrow.getSqlMap().put("dsf", dataScopeFilter(borrow.getCurrentUser(), "o", "a"));
		// 设置分页参数
		borrow.setPage(page);

		// 执行分页查询
		page.setList(borrowDao.findList(borrow));
		return page;
	}

	/**
	 *
	 * @param page
	 * @param borrow
	 * @return
	 */
	public Page<Borrow> findCurrentCirculation(Page<Borrow> page, Borrow borrow) {
		// 生成数据权限过滤条件（dsf为dataScopeFilter的简写，在xml中使用 ${sqlMap.dsf}调用权限SQL）
		borrow.getSqlMap().put("dsf", dataScopeFilter(borrow.getCurrentUser(), "o", "a"));
		// 设置分页参数
		borrow.setPage(page);

		// 执行分页查询
		page.setList(borrowDao.findCurrentCirculation(borrow));
		return page;
	}

	/**
	 * 归还图书
	 * @param page
	 * @param borrow
	 * @return
	 */
	//扫描卡号，显示该用户所借的书籍  和 读者的信息
    public Page<Borrow> rtnbooklist(Page<Borrow> page, Borrow borrow, String cardno){
        // 设置分页参数
        borrow.setPage(page);
        page.setList(this.findborrowListbyCardno(cardno));
        return page;
    }

	//扫描书籍，显示读者信息 和该用户所借的书籍
	public Borrow findBorrowListByBanid(String banid) {
		return borrowDao.findBorrowListByBanid(banid);
	}

	//扫描书籍，显示读者信息 和该用户所借的书籍
	public Borrow rtnbookForBackUpdate(Borrow borrow) {
		return borrowDao.findborrowListAfterUpdate(borrow);
	}

	@Transactional()
	public void saveLog(BorrowLog borrowLog){
			borrowLogDao.insert(borrowLog);
	}

	/**
	 * 根据借阅记录号，查询这条记录
	 * @param zlId
	 * @return
	 */
	public Borrow findOne(String zlId){
		return borrowDao.get(zlId);
	}

	@Transactional()
	public void saveBorrow(Borrow borrow) throws ParseException{
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
		borrow.setUserName(UserUtils.getUser().getLoginName());//操作员

		if(StringUtils.isBlank(borrow.getId())){
			borrow.preInsert();
			borrow.setStatus("1");//0 表示归还，1表示接出
			borrow.setBorDate(sdf.parse(DateUtils.getDate()));//接出日期
			borrow.setRemarks("借出");//备注
			borrowDao.insert(borrow);

            bookStoreDao.borrow(borrow.getBkId());
		}
	}

	@Transactional()
    public void saveback(String zlId, String rtnDate, String userName, String status){
        borrowDao.updateback(zlId, rtnDate, userName, status);
        bookStoreDao.back(zlId);
    }

	@Transactional()
	public void savebrcontinue(String zlId,String continuday,String continurtnday, String userName, String status,int count){
		borrowDao.updatecontinue(zlId, continurtnday, userName, "1", count);//更新借阅表
		borrowContinueDao.insertcontinue(zlId, continuday, continurtnday, userName, "1");//插入续借记录
	}


	@Transactional()
	public void updateCont(String zlId,String continuday,String continurtnday, String userName, String status,int count){
		borrowDao.updatecontinue(zlId, continurtnday, userName, "1",count);//更新借阅表
		borrowContinueDao.updateCont(zlId, continuday, continurtnday, userName, "1");//插入续借记录
	}


	public int getBorrowCount(String rdId) {
		return borrowDao.getBorrowCount(rdId);
	}

    public List<Borrow> findborrowListbyCardno(String rdId) {
        return borrowDao.findborrowListbyCardno(rdId);
    }

	public List<Borrow> findBorrowListbyRdid(String rdId) {
		return borrowDao.findborrowListbyRdid(rdId);
	}

	public int getContinucountbyzlidlist(String zlidlist) {
		return borrowContinueDao.getContinucountbyzlidlist(zlidlist);
	}


	@Transactional()
	public int updateContinuestatus(String zlId, String status) {
		return borrowContinueDao.updateContinuestatus(zlId, status);
	}

	public int findExistBook(String banid){
		return borrowDao.findExistBook(banid);
	}

	public List<Map<String, Integer>> getBooksBorrowAmount(Date begin, Date end, String limit){
		return borrowDao.getBooksBorrowAmount(begin, end, limit);
	}

	public List<Map<String, Integer>> getOneDayBorrowUserAmount(String date){
		return borrowDao.getOneDayBorrowUserAmount(date);
	}

	public List<Map<String, Object>> utilizationToTal(String begin, String end){
		return borrowDao.utilizationToTal(begin, end);
	}
	public List<Map<String, Object>> utilizationBook(String begin, String end){
		return borrowDao.utilizationBook(begin, end);
	}
	public List<Map<String, Object>> utilizationReader(String begin, String end){
		return borrowDao.utilizationReader(begin, end);
	}

	public List<Map<String, Integer>> getreaderStatistics(String type, String begin, String end){
		return borrowDao.getreaderStatistics(type, begin, end);
	}

	public List<Map<String, Object>> outLine(String begin, String end, String now){
		return borrowDao.outLine(begin, end, now);
	}

	public List<Map<String, Object>> bookBorrowStatisticsByType(String begin, String end){
		return borrowDao.bookBorrowStatisticsByType(begin, end);
	}

	public List<Map<String, Object>> bookBorrowStatisticsByLevel(String begin, String end){
		return borrowDao.bookBorrowStatisticsByLevel(begin, end);
	}

	public List<Map<String, Object>> bookBorrowStatisticsByOther(String begin, String end){
		return borrowDao.bookBorrowStatisticsByOther(begin, end);
	}

	public List<Borrow> findBorrowListByReaderType(Borrow borrow){
		return borrowDao.findBorrowListByReaderType(borrow);
	}

    @Transactional()
	public Result borrow_book(String banid, Reader reader, String source) throws ParseException{
		Borrow borrow3 = new Borrow();

		BkBookinfo bookinfo = bookMgrService.getBybanid(banid);
		borrow3.setBkBookinfo(bookinfo);
		borrow3.setBkId(banid);
		ReaderRoler readerRoler = readerService.findReaderRoleByRdid(reader);
		String msg;
		String successCode = Result.FAILURE;
		if(bookinfo == null){
			msg = "这本书没有登记在册，请联系管理员!";
		} else if(readerRoler==null){
			msg = "您还没有进行角色授权，请联系管理员!";
		} else {
			//读者Id
			String rdId = reader.getRdId();
			//书库id
			BkBookstore bookstore = bookinfo.getBookstore();
			// 判断图书是否在管
			if(bookstore.getLeftCount() > 0){
				String placeid = bookstore.getStore();

				List<ReaderRolePlace> bkPlaceList = readerRoler.getReaderRolePlaceList();
				Boolean flag = true;
				for(ReaderRolePlace bkPlace : bkPlaceList){
					if(placeid.equals(bkPlace.getPlaceId())){
						flag = false;
						break;
					}
				}
				if(flag){
					msg = "您不能借阅该书库的图书!";
				}
				else{
					String rdCanBorrowdBooks = readerRoler.getRdCanBorrowdBooks();//可借册数
					String rdCanBorrowDays = readerRoler.getRdCanBorrowDays();//可借天数

					//判断当前用户的状态是否正常  0:正常   1：停用    2：挂失
					String reader_status = reader.getRdState();
					String rdName = reader.getRdName();

					if("1".equals(reader_status)){
						msg = "您的借书卡已经停用，请重新激活!";
					}
					else if("2".equals(reader_status)){
						msg = "您的借书卡已被挂失，请重新激活!";
					}
					else{
						//需要判断用户借出的本书是不是超出了角色的范围 用户可以借出1本，再借发生error
						int already_count = this.getBorrowCount(rdId);
						if((already_count + 1) > Integer.valueOf(rdCanBorrowdBooks)){
							msg = "您的借阅本书已经达到上限，不能借出!";
						}
						else{
							// 该用户是不是有超期的书籍，有的话，也不能借出
							Borrow borrow = new Borrow();
							borrow.setRdId(rdId);
							borrow.setStatus("1");//借出的书籍
							Page<Borrow> page = this.findBorrow(new Page<Borrow>(), borrow);
							boolean isOverDate = false;
							// 有借出记录，需要判断有么有超期的
							if(!page.getList().isEmpty()){
								for(Borrow borrow1 : page.getList()){
									//计算书籍应还日期
									SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
									java.util.Date date = borrow1.getBorDate();
									String str = sdf.format(date);
									String returnday = DateUtils.dateadd(str, Integer.valueOf(rdCanBorrowDays));
									java.util.Date return_date = sdf.parse(returnday);//应还日期
									java.util.Date current_date = sdf.parse(sdf.format(new java.util.Date()));//当前时间
									if(isOverDate = return_date.getTime() < current_date.getTime()){
										break;
									}
								}
							}
							if(isOverDate){
								msg = "您借阅的图书已逾期未还，请还书后再借!";
							}
							else{
								// 正常条件下的借出
								borrow3.setContCnt("0");// 第一次续借次数置为0
								borrow3.setBkId(banid);
								borrow3.setRdId(rdId);
								// 1.生成10位的随机数
								String ZlId = RandomNumUtiles.getRandomNum(8);
								// 2.如果有的话，在重新生成，直到么有重复的项
								while(!StringUtils.isBlank(borrow.getId())){
									ZlId = RandomNumUtiles.getRandomNum(8);
								}
								borrow3.setZlId(ZlId);
								String currentDate = DateUtils.getDate();
								String needRtnDate = DateUtils.dateadd(currentDate, Integer.valueOf(rdCanBorrowDays));
								borrow3.setNeedRtnDate(new SimpleDateFormat("yyyy-MM-dd").parse(needRtnDate));

								if("self".equals(source)){
									borrow3.setUserName(rdName);
								}
								else{
									borrow3.setUserName(UserUtils.getUser().getName());
								}
								borrow3.setSource(source);
								this.saveBorrow(borrow3);

								//日志记录
								BorrowLog borrowLog = new BorrowLog("0", rdId, rdName, "书籍", banid, makeBookName(banid), "0",
										DateUtils.getDateTime(), ZlId, bookStoreService.get(banid).getBkId(),
										UserUtils.getUser().getLoginName(), borrow3.getRtnDate());

                                this.saveLog(borrowLog);
								successCode = Result.SUCCESS;
								msg = "借出成功！";
							}
						}
					}
				}
			}
			else{
				msg = "图书已借出，请咨询管理员！";
			}
		}
		return new Result(successCode, msg, borrow3);
	}

    /**
     * 还书
     * @param banid
     * @return
     */
    @Transactional()
    public Result return_book(String banid){
        String msg = "";
        String successCode = Result.FAILURE;

        if(StringUtils.isNotEmpty(banid)){
            Borrow borrow = this.findBorrowListByBanid(banid);
            if(borrow != null && "1".equals(borrow.getStatus())){
                try{
                    String minRetDays = borrow.getReaderRoler().getMinRetdays();//最小间隔还书天数

                    java.util.Date beforeDate = borrow.getBorDate();
                    java.util.Date afterDate = DateUtils.parseDate(DateUtils.getDate());

                    Double diffDays = DateUtils.getDistanceOfTwoDate(beforeDate, afterDate);
                    if(diffDays.intValue() < Integer.parseInt(minRetDays)){
                        String tempStr = String.valueOf(Integer.parseInt(minRetDays) - diffDays.intValue());
                        msg = "您借阅的图书只能在" + tempStr + "天后进行归还！";
                    }
                    else{
                        // 查询借阅记录
                        Borrow borrowForUpdate = this.findOne(borrow.getZlId());

                        //如果续借次数>0 说明有续借的记录，这时候应该同步一下续借的记录，将该条的记录置为无效0，否则直接归还
                        if(Integer.valueOf(borrowForUpdate.getContCnt()) > 0){
                            this.updateContinuestatus(borrowForUpdate.getZlId(), "0");
                        }
                        this.saveback(borrowForUpdate.getZlId(), DateUtils.getDate(), UserUtils.getUser().getLoginName(), "0");

                        //日志记录
                        String bookName = makeBookName(borrowForUpdate.getBkId());
                        BorrowLog borrowLog = new BorrowLog("1", borrowForUpdate.getRdId(), readerService.getUser(borrowForUpdate.getRdId()).getRdName(),
                                "书籍", borrowForUpdate.getBkId(), bookName, "0",
                                new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new java.util.Date()), borrowForUpdate.getZlId(),
                                bookStoreService.get(borrowForUpdate.getBkId()).getBkId(), UserUtils.getUser().getLoginName());
                        this.saveLog(borrowLog);
                        msg = bookName + "还书成功！";
                        successCode = Result.SUCCESS;
                    }
                }
                catch(Exception e){
					logger.error("还书异常:", e);
                }
            }
            else if(borrow != null && "0".equals(borrow.getStatus())){
                msg = "该本已经完成还书！";
            }
            else{
                borrow = new Borrow();
                msg = "没有查询到该书的借阅记录,或者该书已完成还书！";
            }
			String banId = borrow.getBkId();
			BkBookinfo bkBookinfo = bookMgrService.findFrontSearchByBanId(banId);
            borrow.setBkBookinfo(bkBookinfo);

            return new Result(successCode, msg, borrow);
        }

        return new Result(successCode, msg, null);
    }

    /**
     * 构造bookname+“-”+othername的格式
     * @param bkid
     * @return
     */
    public String makeBookName(String bkid){

        BkBookstore bkBookstore = bookStoreService.get(bkid);
        String bookName = bkBookstore.getBookname();
        String otherName = bkBookstore.getOthername();
        if(StringUtils.isNotEmpty(otherName)){
            return bookName+"-"+otherName;
        }else{
            return bookName;
        }
    }
}
